package com.ssy.lingxi.platform.template.service.serviceimpl.web;

import cn.hutool.core.collection.CollectionUtil;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.constant.member.MemberTypeEnum;
import com.ssy.lingxi.common.constant.member.RoleTypeEnum;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.api.feign.inner.MemberInnerControllerFeign;
import com.ssy.lingxi.member.merchant.api.feign.inner.MemberLevelRightCreditControllerFeign;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.request.MemberFeignIdVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.request.MemberFeignVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.MemberFeignLrcVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.MemberFeignRegisterQueryVO;
import com.ssy.lingxi.platform.manage.api.feign.inner.AreaControllerFeign;
import com.ssy.lingxi.platform.template.service.entity.collect.MemberLogisticsCollect;
import com.ssy.lingxi.platform.template.service.entity.door.MemberLogistics;
import com.ssy.lingxi.platform.template.service.entity.door.QMemberLogistics;
import com.ssy.lingxi.platform.template.service.model.bo.AreaBO;
import com.ssy.lingxi.platform.template.service.model.dto.common.CollectDTO;
import com.ssy.lingxi.platform.template.service.model.dto.common.IdDTO;
import com.ssy.lingxi.platform.template.service.model.dto.common.IdListDTO;
import com.ssy.lingxi.platform.template.service.model.dto.web.SaveLogisticsDTO;
import com.ssy.lingxi.platform.template.service.model.qo.MemberLogisticsQO;
import com.ssy.lingxi.platform.template.service.model.vo.web.MemberLogisticsListVO;
import com.ssy.lingxi.platform.template.service.model.vo.web.MemberLogisticsMainVO;
import com.ssy.lingxi.platform.template.service.repository.MemberLogisticsCollectRepository;
import com.ssy.lingxi.platform.template.service.repository.MemberLogisticsRepository;
import com.ssy.lingxi.platform.template.service.service.web.MemberLogisticsWebService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
 * @author fhj
 * @version 2.0.0
 * @menu web - 会员物流门户 - 业务实现层
 * @date 2021/04/14
 */
@Slf4j
@Service
public class MemberLogisticsWebServiceImpl implements MemberLogisticsWebService {

    @Resource
    private JPAQueryFactory jpaQueryFactory;
    @Resource
    private MemberLogisticsRepository memberLogisticsRepository;
    @Resource
    private MemberLevelRightCreditControllerFeign memberLevelRightCreditControllerFeign;
    @Resource
    private MemberInnerControllerFeign memberInnerControllerFeign;
    @Resource
    private AreaControllerFeign areaControllerFeign;
    @Resource
    private MemberLogisticsCollectRepository memberLogisticsCollectRepository;

    @Override
    @Transactional
    @ApiOperation(value = "保存当前登录会员的物流门户")
    public Wrapper<Void> saveCurrMemberLogistics(SaveLogisticsDTO dto, UserLoginCacheDTO user) {
        //校验（只有是服务提供者且企业类型是企业会员或个人会员才能创建物流门户
        if (!user.getMemberRoleType().equals(RoleTypeEnum.SERVICE_PROVIDER.getCode())) {
            return Wrapper.fail("角色类型不是服务提供者, 不能创建物流门户");
        }
        if (!(user.getMemberType().equals(MemberTypeEnum.MERCHANT.getCode()) || user.getMemberType().equals(MemberTypeEnum.MERCHANT_PERSONAL.getCode()))) {
            return Wrapper.fail("会员类型不是企业会员或个人会员, 不能创建物流门户");
        }

        //默认省、市编码都为0（所有/所有）
        List<String> provinceCodes = Stream.of("0").collect(toList());
        List<String> cityCodes = Stream.of("0").collect(toList());
        if (dto.getAreaBOList().stream().noneMatch(a -> a.getProvinceCode().equals("0"))) {
            provinceCodes = dto.getAreaBOList().stream().map(AreaBO::getProvinceCode).collect(Collectors.toList());
            cityCodes = dto.getAreaBOList().stream().filter(a -> !a.getCityCode().equals("0")).map(AreaBO::getCityCode).collect(Collectors.toList());

            List<String> feignCodes = dto.getAreaBOList().stream().filter(a -> a.getCityCode().equals("0")).map(AreaBO::getProvinceCode).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(feignCodes)) {
                Wrapper<List<String>> cityCodesWrapper = areaControllerFeign.findCityCodeByProvinceCode(feignCodes);
                if (cityCodesWrapper.getCode() == ResponseCode.SUCCESS.getCode() && CollectionUtil.isNotEmpty(cityCodesWrapper.getData())) {
                    cityCodes.addAll(cityCodesWrapper.getData());
                }
            }
        }

        //调用会员服务 -> 根据会员ID和角色ID获取平台会员的等级、注册年数、信用积分
        MemberFeignVO memberFeignVO = new MemberFeignVO();
        memberFeignVO.setMemberId(user.getMemberId());
        memberFeignVO.setRoleId(user.getMemberRoleId());
        Wrapper<MemberFeignLrcVO> platformMemberLrcWrapper = memberLevelRightCreditControllerFeign.getPlatformMemberLrc(memberFeignVO);
        if (platformMemberLrcWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            log.error("调用会员服务失败：{}", platformMemberLrcWrapper.getMessage());
            return Wrapper.fail(ResponseCode.SERVICE_MERCHANT_MEMBER_ERROR);
        }
        //调用会员服务 -> 根据会员Id查询会员注册信息
        MemberFeignIdVO memberFeignIdVO = new MemberFeignIdVO();
        memberFeignIdVO.setMemberId(user.getMemberId());
        Wrapper<MemberFeignRegisterQueryVO> memberRegisterInfoWrapper = memberInnerControllerFeign.getMemberRegisterInfo(memberFeignIdVO);
        if (memberRegisterInfoWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            log.error("调用会员服务失败：{}", memberRegisterInfoWrapper.getMessage());
        }

        //保存会员物流门户信息
        MemberLogistics memberLogistics = memberLogisticsRepository.findByMemberIdAndRoleId(user.getMemberId(), user.getMemberRoleId());
        memberLogistics = memberLogistics != null ? memberLogistics : new MemberLogistics();
        memberLogistics.setMemberId(user.getMemberId());
        memberLogistics.setRoleId(user.getMemberRoleId());
        memberLogistics.setMainBusiness(dto.getMainBusiness());
        memberLogistics.setAreaBOList(dto.getAreaBOList());
        memberLogistics.setLogo(dto.getLogo());
        memberLogistics.setDescribe(dto.getDescribe());
        memberLogistics.setSlideshowBOList(dto.getSlideshowBOList());
        memberLogistics.setCompanyPics(dto.getCompanyPics());
        memberLogistics.setHonorPics(dto.getHonorPics());
        memberLogistics.setAlbumName(dto.getAlbumName());
        memberLogistics.setAlbumUrl(dto.getAlbumUrl());
        memberLogistics.setAboutSeo(dto.getAboutSeo());
        memberLogistics.setAreas(dto.getAreaBOList().stream().map(a -> a.getProvince() + "/" + a.getCity()).collect(Collectors.joining("，")));
        memberLogistics.setProvincesCodeList(String.join("，", provinceCodes));
        memberLogistics.setCityCodeList(String.join("，", cityCodes));
        memberLogistics.setMemberName(user.getCompany());
        memberLogistics.setLevelTag(platformMemberLrcWrapper.getData().getLevelTag());
        memberLogistics.setRegisterYears(platformMemberLrcWrapper.getData().getRegisterYears());
        memberLogistics.setCreditPoint(platformMemberLrcWrapper.getData().getCreditPoint());
        memberLogistics.setRegisteredCapital(memberRegisterInfoWrapper.getData() != null ? memberRegisterInfoWrapper.getData().getRegisteredCapital() : null);
        memberLogistics.setEstablishmentDate(memberRegisterInfoWrapper.getData() != null ? memberRegisterInfoWrapper.getData().getEstablishmentDate() : null);
        memberLogistics.setBusinessLicence(memberRegisterInfoWrapper.getData() != null ? memberRegisterInfoWrapper.getData().getBusinessLicence() : null);
        memberLogistics.setRegisterArea(memberRegisterInfoWrapper.getData() != null ? memberRegisterInfoWrapper.getData().getRegisterArea() : null);
        memberLogistics.setRegisterAddress(memberRegisterInfoWrapper.getData() != null ? memberRegisterInfoWrapper.getData().getRegisterAddress() : null);
        memberLogisticsRepository.saveAndFlush(memberLogistics);

        return Wrapper.success();
    }

    @Override
    @ApiOperation(value = "获取当前登录会员的物流门户")
    public Wrapper<MemberLogistics> findCurrMemberLogistics(UserLoginCacheDTO user) {
        return Wrapper.success(memberLogisticsRepository.findByMemberIdAndRoleId(user.getMemberId(), user.getMemberRoleId()));
    }

    @Override
    @ApiOperation(value = "物流门户列表")
    public Wrapper<PageData<MemberLogisticsListVO>> memberLogisticsList(MemberLogisticsQO qo) {
        //查询表实体 - 物流门户
        QMemberLogistics memberLogistics = QMemberLogistics.memberLogistics;

        //查询条件构造 - 搜索条件
        BooleanBuilder predicates = new BooleanBuilder();
        //搜索条件 - 省编码。
        if (StringUtils.isNotBlank(qo.getProvinceCode())) {
            predicates.and(
                    memberLogistics.provincesCodeList.like("%" + qo.getProvinceCode() + "%")
                            .or(memberLogistics.provincesCodeList.eq("0"))
            );
        }
        //搜索条件 - 市编码。
        if (StringUtils.isNotBlank(qo.getCityCode())) {
            predicates.and(
                    memberLogistics.cityCodeList.like("%" + qo.getCityCode() + "%")
                            .or(memberLogistics.cityCodeList.eq("0"))
            );
        }
        //查询
        JPAQuery<MemberLogistics> query = jpaQueryFactory.select(memberLogistics).from(memberLogistics).where(predicates);

        //总记录数
        long totalCount = query.fetchCount();

        //列表数据
        List<MemberLogistics> list = query.orderBy(memberLogistics.createTime.desc()).offset((long) (qo.getCurrent() - 1) * qo.getPageSize()).limit(qo.getPageSize()).fetch();
        if (CollectionUtil.isEmpty(list)) {
            return Wrapper.success(new PageData<>(0L, new ArrayList<>()));
        }

        //封装
        List<MemberLogisticsListVO> memberLogisticsListVOList = list.stream().map(a -> {
            //拷贝
            MemberLogisticsListVO vo = new MemberLogisticsListVO();
            BeanUtils.copyProperties(a, vo);

            //格式化主营业务
            vo.setMainBusiness(StringUtils.join(a.getMainBusiness(), "|"));

            //默认先满星
            if (a.getAvgTradeCommentStar() == null || a.getAvgTradeCommentStar() == 0) {
                a.setAvgTradeCommentStar(5);
            }

            return vo;
        }).collect(toList());

        return Wrapper.success(new PageData<>(totalCount, memberLogisticsListVOList));
    }

    @Override
    @ApiOperation(value = "物流门户主页")
    public Wrapper<MemberLogisticsMainVO> memberLogisticsMain(IdDTO dto, UserLoginCacheDTO user) {
        //获取物流门户
        MemberLogistics memberLogistics = memberLogisticsRepository.findById(dto.getId()).orElse(null);
        if (memberLogistics == null) {
            return Wrapper.fail("根据ID找不到物流门户");
        }

        //拷贝
        MemberLogisticsMainVO memberLogisticsMainVO = new MemberLogisticsMainVO();
        BeanUtils.copyProperties(memberLogistics, memberLogisticsMainVO);

        //收藏状态
        if (user != null) {
            memberLogisticsMainVO.setCollectStatus(memberLogisticsCollectRepository.existsByLogisticsIdAndMemberIdAndUserId(memberLogistics.getId(), user.getMemberId(), user.getUserId()));
        }

        //默认先满星
        if (memberLogisticsMainVO.getAvgTradeCommentStar() == null || memberLogisticsMainVO.getAvgTradeCommentStar() == 0) {
            memberLogisticsMainVO.setAvgTradeCommentStar(5);
        }

        return Wrapper.success(memberLogisticsMainVO);
    }

    @Override
    @ApiOperation(value = "根据物流门户ID集合获取物流门户")
    public Wrapper<List<MemberLogistics>> findByIdIn(IdListDTO dto) {
        return Wrapper.success(memberLogisticsRepository.findAllById(dto.getIdList()).stream().sorted(Comparator.comparingInt(a -> dto.getIdList().indexOf(a.getId()))).collect(toList()));
    }

    @Override
    @Transactional
    @ApiOperation(value = "收藏/取消收藏")
    public Wrapper<Void> collect(CollectDTO dto, UserLoginCacheDTO user) {
        if (dto.getStatus()) {
            if (memberLogisticsCollectRepository.existsByLogisticsIdAndMemberIdAndUserId(dto.getId(), user.getMemberId(), user.getUserId())) {
                return Wrapper.fail("不能重复收藏，请刷新页面");
            }
            MemberLogisticsCollect collect = new MemberLogisticsCollect();
            collect.setLogisticsId(dto.getId());
            collect.setMemberId(user.getMemberId());
            collect.setUserId(user.getUserId());
            memberLogisticsCollectRepository.saveAndFlush(collect);
        } else {
            memberLogisticsCollectRepository.deleteByLogisticsIdAndMemberIdAndUserId(dto.getId(), user.getMemberId(), user.getUserId());
        }

        return Wrapper.success();
    }

    @Override
    @ApiOperation(value = "收藏列表")
    public Wrapper<PageData<MemberLogistics>> collectList(PageVO dto, UserLoginCacheDTO user) {
        //按收藏时间倒序获取当前用户收藏的物流门户ID
        Pageable pageable = PageRequest.of(dto.getCurrent() - 1, dto.getPageSize(), Sort.by("createTime").descending());
        Page<MemberLogisticsCollect> page = memberLogisticsCollectRepository.findAllByMemberIdAndUserId(user.getMemberId(), user.getUserId(), pageable);
        List<MemberLogisticsCollect> memberLogisticsCollectList = page.getContent();
        if (CollectionUtil.isEmpty(memberLogisticsCollectList)) {
            log.info("当前用户没有收藏的物流门户");
            return Wrapper.success(new PageData<>(0L, new ArrayList<>()));
        }
        List<Long> memberLogisticsIdList = memberLogisticsCollectList.stream().map(MemberLogisticsCollect::getLogisticsId).collect(toList());

        //根据收藏的物流ID获取物流门户
        List<MemberLogistics> memberLogisticsList = memberLogisticsRepository.findAllById(memberLogisticsIdList);

        //组装收藏时间
        memberLogisticsList = memberLogisticsList.stream().peek(a -> a.setCreateTime(
                memberLogisticsCollectList.stream().filter(b ->
                        b.getLogisticsId().equals(a.getId())
                ).map(MemberLogisticsCollect::getCreateTime).findFirst().orElse(null)
        )).sorted(Comparator.comparingInt(a -> memberLogisticsIdList.indexOf(a.getId()))).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(page.getTotalElements(), memberLogisticsList));
    }
}
